﻿namespace PerpetuumSoft.InstrumentationPDA
{
    using PerpetuumSoft.InstrumentationPDA.Mathematics;
    using System;
    using System.Drawing;

    public abstract class CircularControlBase : ValuePresenter
    {
        private Size center = new Size(0, 0);
        private bool reverseScale = true;
        private int startAngle = 0x13b;
        private int totalAngle = 270;

        protected CircularControlBase()
        {
        }

        protected decimal AngleToValue(decimal angle)
        {
            if (angle < (this.StartAngle - ((360 - this.TotalAngle) / 2)))
            {
                angle += 360M;
            }
            return (base.Minimum + ((base.Maximum - base.Minimum) * ((angle - this.StartAngle) / this.TotalAngle)));
        }

        protected decimal PercentToAngle(decimal value)
        {
            return (this.StartAngle + (value * this.TotalAngle));
        }

        protected override Vector ToPoint(decimal value)
        {
            return this.ToPoint(value, 10M);
        }

        protected Vector ToPoint(decimal value, decimal radius)
        {
            decimal num;
            if (this.reverseScale)
            {
                num = this.StartAngle + (this.TotalAngle * (1M - base.ValueToPercent(value)));
            }
            else
            {
                num = this.StartAngle + (this.TotalAngle * base.ValueToPercent(value));
            }
            Vector vector = Vector.FromPolar(radius, num * 0.0174532925199433M);
            vector.X += this.CenterPoint.X;
            vector.Y = this.CenterPoint.Y - vector.Y;
            return vector;
        }

        protected override decimal ToValue(Vector v)
        {
            decimal num3;
            bool flag;
            bool flag2;
            decimal num = v.X - this.CenterPoint.X;
            decimal num2 = v.Y - this.CenterPoint.Y;
            if (num == 0M)
            {
                num3 = (num2 < 0M) ? 90 : -90;
            }
            else
            {
                decimal num4 = (decimal) ((Math.Atan((double) (-num2 / num)) * 180.0) / 3.1415926535897931);
                if (num > 0M)
                {
                    num3 = num4;
                }
                else
                {
                    num3 = (num2 > 0M) ? (num4 - 180M) : (num4 + 180M);
                }
            }
            decimal num5 = ((((num3 + 360M) % 360M) - this.startAngle) + 360M) % 360M;
            decimal num6 = num5 / this.totalAngle;
            if (this.reverseScale)
            {
                num6 = 1M - num6;
            }
            if ((num6 > 0M) && (num6 < 1M))
            {
                return base.PercentToValue(num6);
            }
            Vector vector = this.ToPoint((base.Maximum + base.Minimum) / 2M);
            if (vector.X != this.CenterPoint.X)
            {
                decimal num7 = (vector.Y - this.CenterPoint.Y) / (vector.X - this.CenterPoint.X);
                flag = (((v.X - this.CenterPoint.X) * num7) + this.CenterPoint.Y) < v.Y;
                v = this.ToPoint(base.Minimum);
                flag2 = (((v.X - this.CenterPoint.X) * num7) + this.CenterPoint.Y) < v.Y;
            }
            else
            {
                flag = vector.X < this.CenterPoint.X;
                flag2 = (this.StartAngle > 90) && (this.StartAngle < 270);
            }
            if ((flag && flag2) || (!flag && !flag2))
            {
                return base.Minimum;
            }
            return base.Maximum;
        }

        protected decimal ValueToAngle(decimal value)
        {
            return this.PercentToAngle(base.ValueToPercent(value));
        }

        public Size Center
        {
            get
            {
                return this.center;
            }
            set
            {
                if (this.center != value)
                {
                    this.center = value;
                    base.InvalidateStatic();
                }
            }
        }

        protected Vector CenterPoint
        {
            get
            {
                return (new Vector(base.Width / 2, base.Height / 2) + new Vector(this.Center));
            }
        }

        public int CurrentAngle
        {
            get
            {
                return (this.StartAngle + base.Round(base.ValueToPercent(base.Value) * this.TotalAngle));
            }
            set
            {
                base.Value = this.AngleToValue(value);
            }
        }

        public int EndAngle
        {
            get
            {
                return ((this.startAngle + this.totalAngle) % 360);
            }
            set
            {
                if ((this.startAngle + this.totalAngle) != value)
                {
                    if (value < this.startAngle)
                    {
                        this.TotalAngle = (value - this.startAngle) + 360;
                    }
                    else
                    {
                        this.TotalAngle = value - this.startAngle;
                    }
                }
            }
        }

        public bool ReverseScale
        {
            get
            {
                return this.reverseScale;
            }
            set
            {
                if (value != this.reverseScale)
                {
                    this.reverseScale = value;
                    base.InvalidateStatic();
                }
            }
        }

        public int StartAngle
        {
            get
            {
                return this.startAngle;
            }
            set
            {
                value = ((value % 360) + 360) % 360;
                if (this.startAngle != value)
                {
                    this.startAngle = value;
                    base.InvalidateStatic();
                }
            }
        }

        public int TotalAngle
        {
            get
            {
                return this.totalAngle;
            }
            set
            {
                if (value == 0)
                {
                    value = 1;
                }
                else if ((value % 360) == 0)
                {
                    value = 360;
                }
                else
                {
                    value = ((value % 360) + 360) % 360;
                }
                if (this.totalAngle != value)
                {
                    this.totalAngle = value;
                    base.InvalidateStatic();
                }
            }
        }
    }
}

